#include <QX11Info>
#include <QtDebug>

#include "myapplication.h"

MyApplication::MyApplication(int & argc, char ** argv)
    : QApplication(argc, argv)
{
    xkbAvailable = false;

    // try to init xkb
    Display* display = QX11Info::display();

    int opcode;
    int errorBase;
    int major = XkbMajorVersion;
    int minor = XkbMinorVersion;
    int status;

    // check XKB version
    if (!XkbLibraryVersion(&major, &minor)) {
        qWarning(QObject::tr("This program was built against XKB extension library\n"
      "version %1.%2, but is run with the library version %3.%4.\n"
      "This may cause various problems and even result in a complete\n"
      "failure to function\n").arg(XkbMajorVersion).arg(XkbMinorVersion).arg(major).arg(minor).toAscii());
    }

    // initialize the extension
    xkbAvailable = XkbQueryExtension(display, &opcode, &eventCode, &errorBase, &major, &minor);
    if (!xkbAvailable) {
        qCritical(QObject::tr("The X Server does not support a compatible XKB extension.").toAscii());
    } else {
        // register for XKB events
        //// group state change, i.e. the current group changed:
        XkbSelectEventDetails(display, XkbUseCoreKbd, XkbControlsNotify,
          XkbModifierStateMask | XkbGroupStateMask, XkbModifierStateMask | XkbGroupStateMask);

        status = XkbSelectEvents(display, XkbUseCoreKbd,
            XkbIndicatorStateNotifyMask | XkbNewKeyboardNotifyMask,
            XkbIndicatorStateNotifyMask | XkbNewKeyboardNotifyMask);
        if (status != True) {
            qCritical(QObject::tr("Unable to get indicator events").toAscii());
            xkbAvailable = false;
        }
    }

}

bool MyApplication::x11EventFilter(XEvent* event)
{
    if (event->type == eventCode) {
        // XKB event
        XkbEvent *xkbEvent = (XkbEvent *) event;

        if (XkbIndicatorStateNotify == xkbEvent->any.xkb_type) {
            // emit corresponding signal
            emit indicatorStateChanged(xkbEvent->indicators.state);
        }
    }
    return false;
}

void MyApplication::forceGetIndicatorsState()
{
    unsigned int ledstate;
    if (XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &ledstate) != Success) {
        qWarning(QObject::tr("Unable to detect keyboard leds state from XKB").toAscii());
        return;
    }
    emit indicatorStateChanged(ledstate);
}
